<?php
/**
 * 模型工厂类
 *
 * @package util.dar
 * @version $Id: IDarModelFactory.php 323 2008-05-14 05:49:20Z iwind $
 * @since 0.1
 */
class IDarModelFactory  extends IObject {
	private $models = array();
	private static $instance;
	private $provider;
	private $config;
	
	/**
	 * 构造
	 *
	 * @since 0.1
	 */
	private function __construct() {
		
	}
	
	/**
	 * 取得实例
	 *
	 * @return IDarModelFactory
	 * @since 0.1
	 */
	public static function getInstance() {
		if (self::$instance == null) {
			self::$instance = new IDarModelFactory();
		}
		return self::$instance;
	}
	
	/**
	 * 取得驱动
	 * 
	 * 从0.2.1开始，如果dsnXml未定义，则自动取 SqlMapConfig.xml，或者sqlmap.conf.php
	 *
	 * @return IDarProvider
	 * @since 0.1
	 */
	public function getProvider() {
		if ($this->provider == null) {
			$foundConfig = isset($this->config["dsnXml"]);
			if (!$foundConfig && !isset($this->config["dsnXml"]) && is_file(IFRAMEWORK_CONFIG_DIRECTORY . "/SqlMapConfig.xml")) {
				$this->config["dsnXml"] = IFRAMEWORK_CONFIG_DIRECTORY . "/SqlMapConfig.xml";
				$foundConfig = true;
			}
			
			if (!$foundConfig && !isset($this->config["sqlmap"]) && is_file(IFRAMEWORK_CONFIG_DIRECTORY . "/sqlmap.conf.php")) {
				$this->config["dsnXml"] = IFRAMEWORK_CONFIG_DIRECTORY . "/sqlmap.conf.php";
				$foundConfig = true;
			}
			if (isset($this->config["sqlmap"])) {
				$this->config["dsnXml"] = $this->config["sqlmap"];
			}
			if (!isset($this->config["dsnXml"])) {
				throw new IDarException("sqlmap driver must be defined");
			}
			
			$this->provider = new IDarProvider($this->config["dsnXml"]);
		}
		return $this->provider;
	}
	
	/**
	 * 加载配置
	 * 
	 * 一个配置的例子：
	 * <pre>
	 * $config = array(
	 * 	"dsnXml"=>"config/SqlMapConfig.xml"//dsn选项配置
	 * );
	 * </pre>
	 * 
	 * @param array $config dar配置
	 * @since 0.1
	 */
	public function load(array $config) {
		$this->config = $config;
	}
	
	/**
	 * 取得模型
	 *
	 * @param string $name 模型名
	 * @return IDarModel
	 * @since 0.1
	 */
	public function getModel($name) {
		if (array_key_exists($name, $this->models)) {
			return $this->models[$name];
		}
		
		$class = $name;
		import($class);
		if (!class_exists($class, false)) {
			throw new IDarException("model '{$class}' or class '{$class}' doest not exist");
		}
		if (!is_subclass_of($class, "IDarDomain")) {
			throw new IDarException("model class '{$class}' must be subclass of IDarDomain");
		}
		if (array_key_exists($name, $this->models)) {
			return $this->models[$name];
		}
		
		//取到配置
		$vars = get_class_vars($class);
		if (!isset($vars["MODEL"])) {//从0.2.1起，不再抛出异常
			$config = array();
		}
		else {
			$config = $vars["MODEL"];
		}
		if (!isset($config["tblName"])) {
			$config["tblName"] = native::nameToC($class);
		}
		
		//生成model
		$model = new IDarModel();
		$model->setName($class);
		$model->setDomainClass($class);
		$model->setProvider($this->getProvider());//@todo: 给每一个model配置一个provider
		
		//生成表格
		if (!isset($config["fields"])) {
			$table = IDarTable::autoCreate($model->getProvider(), $class, $config);
		}
		else {
			$table = IDarTable::create($class, $config);
		}
		$model->setTable($table);
		
		//加入到容器
		$this->models[$class] = $model;
		return $model;
	}
}

?>